package com.shinewind.sso.util;

import com.shinewind.sso.entity.JwtProperties;
import io.jsonwebtoken.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.stream.Collectors;

@Component
@EnableConfigurationProperties(JwtProperties.class)
public class JwtTemplate {
    @Autowired
    private JwtProperties jwtProperties;
    //获得token
    public String createJwt(String uid,String username, Collection<? extends GrantedAuthority> rolesList){
        //指定签名时的算法
        SignatureAlgorithm sign = SignatureAlgorithm.HS256;
        //生成Jwt的时间
        long nowCurrentMillis = System.currentTimeMillis();
        Calendar instance = Calendar.getInstance();
        instance.add(Calendar.MINUTE,30);
        //有效载荷
        Map<String, Object> claims = new HashMap<>();
        claims.put("uid",uid);
        claims.put("nam",username);
        List<String> authorities = rolesList.stream().map(authority ->{
            return authority.getAuthority();
        }).collect(Collectors.toList());
        claims.put("rol",authorities);
        claims.put("pub",new Date(nowCurrentMillis));
        //创建jwt对象
        JwtBuilder jwtBuilder = Jwts.builder();
        jwtBuilder.setHeaderParam("typ","JWT");
        jwtBuilder.setClaims(claims);
        jwtBuilder.setExpiration(instance.getTime());
        jwtBuilder.signWith(sign,jwtProperties.getSecretKey());

        String jwtStr = jwtBuilder.compact();
        return jwtStr;
    }
    //解密token
    public Claims parseJwt(String jwt){
        Claims claims;
        try{
            claims = Jwts.parser().setSigningKey(jwtProperties.getSecretKey())
                    .parseClaimsJws(jwt)
                    .getBody();
        }
        catch(ExpiredJwtException e){
            claims = e.getClaims();
        }
        return claims;
    }
    //判断token是否过期
    public Boolean isJwtExpired(String jwt){
        //解密token并获取令牌过期时间
        Claims claims = parseJwt(jwt);
        Date expiration = claims.getExpiration();
        //判断当前日期是否在过期日期之前
        return expiration.before(new Date());
    }
    //验证token
    public Boolean ValidateToken(String jwt){
        return (!isJwtExpired(jwt));
    }
}
